home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / varia / interp18.lha / interp-1.8 / parser.y < prev    next >
Text File  |  1990-01-22  |  5KB  |  192 lines

  1. %{
  2. // parser.y --- a description of the grammar for the bison parser generator.
  3. // Copyright (C) 1989 Carey Richard Murphey.
  4. // (rich@rice.edu) 5310 Rutherglenn, Houston, TX 77096
  5.  
  6. // This program is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 1, or (at your option)
  9. // any later version.
  10.  
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software
  18. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. #define YYDEBUG 1        /* 0 for no debugging, 1 for debugging */
  21. #include <stream.h>
  22. #include <math.h>
  23. #include <ctype.h>
  24. #include "parser.h"
  25. extern "C" double pow(double, double);
  26. enum declaration_enum {DOUBLE_TYPE, INT_TYPE};
  27. declaration_enum declaration_type;
  28. %}
  29. %union {
  30.   double     valu;        /* float numbers. */
  31.   char     * idnt;        /* identifiers */
  32.   String   * name;        /* symbol names */
  33.   Node     * nodp;        /* AST node pointers */
  34.   Sym      * symp;        /* AST symbol pointers */
  35. }
  36.  
  37. %token <valu> WHILE IF SYNTAXOF DOUBLE_DECL INT_DECL
  38. %token <valu> NUM
  39. %token <idnt> IDENT
  40. %type  <name> identifier
  41. %type  <nodp> expr statement statement_list
  42. %type  <nodp> declaration_list declaration_element declaration_start
  43. %type  <symp> sym new_symbol
  44. %type  <valu> eval_now
  45.  
  46. %right '='
  47. %left '-' '+'
  48. %left '*' '/'
  49. %left NEG            /* Negation--unary minus */
  50. %left INCR DECR            /* Increment (++) and Decrement (--) */
  51. %right '^'            /* Exponentiation        */
  52. %%
  53.  
  54. input:
  55.       /* empty */
  56.     | input eval_now
  57.     ;
  58. eval_now:
  59.       statement        { $1->eval ();}
  60.     | error ';'        { yyerror ("\tbad statement."); yyerrok;}
  61.     | ';'            {}
  62.     ;
  63. statement:
  64.       sym '=' expr ';'    { $$ = new Assign ($1, $3);}
  65.     | expr ';'        { $$ = $1;}
  66.     | '{'            { context.open ();}
  67.       statement_list '}'    { $$ = $3; context.close ();}
  68.     | SYNTAXOF statement    { $$ = $2; cerr << "\n// " << $2 << "\n";}
  69.     | WHILE '(' expr ')' statement
  70.                 { $$ = new While ($3, $5);}
  71.     | IF '(' expr ')' statement
  72.                 { $$ = new If ($3, $5);}
  73.     | declaration_list ';'    { $$ = $1;}
  74.     ;
  75. statement_list:
  76.       statement        { $$ = $1;}
  77.     | statement_list statement
  78.                 { $$ = new Statements ($1, $2);}
  79.     ;
  80. declaration_list:
  81.       declaration_start declaration_element
  82.                 { $$ = $2;}
  83.     | declaration_list ',' declaration_element
  84.                 { $$ = new Statements ($1, $3);}
  85.     ;
  86. declaration_element:
  87.       new_symbol '=' expr    { $$ = new Assign ($1, $3);}
  88.     | new_symbol        { $$ = $1;}
  89.     ;
  90. new_symbol:
  91.       identifier        { if (context.top_level(*$1))
  92.                     {
  93.                       cerr << "\n// " << *$1
  94.                     << " is already defined.\n"; YYERROR;
  95.                     }
  96.                   else
  97.                     {
  98.                       Table t = context.top_table ();
  99.                       switch (declaration_type)
  100.                     {
  101.                     case DOUBLE_TYPE:
  102.                       (*t)[*$1] = new Double_Pointer (0.);
  103.                       break;
  104.                     case INT_TYPE:
  105.                       (*t)[*$1] = new Int_Pointer (0);
  106.                       break;
  107.                     }
  108.                       $$ = new Sym (*$1, t);
  109.                     }
  110.                 }
  111.     | identifier '('    { if (context.top_level(*$1))
  112.                     {
  113.                       cerr << "\n// " << *$1
  114.                     << " is already defined.\n"; YYERROR;
  115.                     }
  116.                     context.open ();
  117.                 }
  118.       arg_list ')'        { context.close ();
  119.                   Table t = context.top_table ();
  120.                   switch (declaration_type)
  121.                     {
  122.                     case DOUBLE_TYPE:
  123.                       (*t)[*$1] = new Double_Function (0.);
  124.                       break;
  125.                     case INT_TYPE:
  126.                       (*t)[*$1] = new Int_Function (0);
  127.                       break;
  128.                     }
  129.                   $$ = new Sym (*$1, t);
  130.                 }
  131.         ;
  132. arg_list:
  133.       arg_list        { ;
  134.                   Table t = context.top_table ();
  135.                   $$ = $2;}
  136.     | DOUBLE_DECL identifier
  137.                 { ;
  138.                   Table t = context.top_table ();
  139.                   (*t)[*$1] = new Double_Pointer (0.);
  140.                 }
  141.     | arg_list ',' arg_element
  142.                 { $$ = new Statements ($1, $3);}
  143.     ;
  144. arg_element:
  145.       new_symbol        { $$ = $1;}
  146.     ;
  147.  
  148. declaration_start:
  149.       DOUBLE_DECL        { declaration_type = DOUBLE_TYPE;}
  150.     | INT_DECL        { declaration_type = INT_TYPE;}
  151.     ;
  152. expr:
  153.       NUM            { $$ = new Double ($1);}
  154.     | expr '+' expr        { $$ = new Plus ($1, $3);}
  155.     | expr '-' expr        { $$ = new Minus ($1, $3);}
  156.     | expr '*' expr        { $$ = new Times ($1, $3);}
  157.     | expr '/' expr        { $$ = new Divide ($1, $3);}
  158.     | '-' expr %prec NEG    { $$ = new Uminus ($2);}
  159.     | expr '^' expr        { $$ = new Pow ($1, $3);}
  160.     | sym INCR        { $$ = new PostIncrement ($1);}
  161.     | sym DECR        { $$ = new PostDecrement ($1);}
  162.     | INCR sym        { $$ = new PreIncrement ($2);}
  163.     | DECR sym        { $$ = new PreDecrement ($2);}
  164.     | identifier '(' expr ')'
  165.                 { if (!context.contains(*$1))
  166.                     {
  167.                       cerr << "\n// " << *$1
  168.                     << " is used but not declared.\n";
  169.                       YYERROR;
  170.                     }
  171.                   else
  172.                     $$ = new Func (new Sym (*$1,
  173.                         context.table (*$1)), $3);}
  174.     | sym            { $$ = $1;}
  175.     | '(' expr ')'        { $$ = $2;}
  176.     | '(' error ')'        { yyerror ("bad expression."); yyerrok;}
  177.     ;
  178. sym :
  179.       identifier        { if (!context.contains(*$1))
  180.                     {
  181.                       cerr << "\n// " << *$1
  182.                     << " is used but not declared.\n";
  183.                       YYERROR;
  184.                     }
  185.                   else
  186.                     $$ = new Sym (*$1, context.table (*$1));}
  187.     ;
  188. identifier :
  189.       IDENT            { $$ = new String ($1); /* delete after use! */}
  190.     ;
  191. %%
  192.